package interfaces

import (
	"api-gateway-center/config"
	model2 "api-gateway-center/domain/loadBanlance/model"
	service2 "api-gateway-center/domain/loadBanlance/service"
	"api-gateway-center/domain/manage/model"
	"api-gateway-center/domain/manage/service"
	"api-gateway-center/infrastructure/repository"
	ResponseCode "api-gateway-center/types/enum"
	Response "api-gateway-center/types/model"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
)

type GatewayConfigManageController struct {
	service              *service.ConfigManageService
	loadBalancingService *service2.LoadBalancingService
}

func NewGatewayConfigManageController() *GatewayConfigManageController {
	loadBalancingService := &service2.LoadBalancingService{}
	manageRepository := repository.NewConfigManageRepository(config.DB)
	manageService := service.NewConfigManageService(manageRepository)
	return &GatewayConfigManageController{service: manageService, loadBalancingService: loadBalancingService}
}
func (this *GatewayConfigManageController) GatewayConfigManage(router *gin.Engine) {
	config := router.Group("/wg/admin/config")
	{
		config.GET("/queryApplicationSystemRichInfo", func(context *gin.Context) {
			gatewayId := context.Query("gatewayId")
			systemId := context.Query("systemId")
			systemRichInfo, err := this.service.QueryApplicationSystemRichInfo(systemId, gatewayId)
			if err != nil {
				context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.UN_ERROR.Code, ResponseCode.UN_ERROR.Info, false))
				return
			}
			context.JSON(http.StatusOK, Response.NewResponse[*model.ApplicationSystemRichInfo](ResponseCode.SUCCESS.Code, ResponseCode.SUCCESS.Info, systemRichInfo))
		})
		config.POST("/registerGateway", func(context *gin.Context) {
			//1. 信息转换
			data, _ := context.GetRawData()
			var gatewayServerDetail GatewayServerDetail
			err := json.Unmarshal(data, &gatewayServerDetail)
			if err != nil {
				context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.UN_ERROR.Code, ResponseCode.UN_ERROR.Info, false))
				return
			}
			//2. 注册网关信息
			err = this.service.RegisterGatewayServerNode(gatewayServerDetail.GroupId,
				gatewayServerDetail.GatewayId,
				gatewayServerDetail.GatewayName,
				gatewayServerDetail.GatewayAddress)
			if err != nil {
				log.Println("注册网关信息失败", err)
				context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.UN_ERROR.Code, ResponseCode.UN_ERROR.Info, false))
				return
			}
			//3. 读取最新网关数据
			serverDetailVOS, err := this.service.QueryGatewayServerDetailList()
			if err != nil {
				context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.UN_ERROR.Code, ResponseCode.UN_ERROR.Info, false))
				return
			}
			//4. 更新nginx
			err = this.buildNginx(serverDetailVOS)
			if err != nil {
				log.Println("更新nginx失败", err)
				context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.UN_ERROR.Code, ResponseCode.UN_ERROR.Info, false))
				return
			}
			context.JSON(http.StatusOK, Response.NewResponse(ResponseCode.SUCCESS.Code, ResponseCode.SUCCESS.Info, true))
		})
	}
}

type GatewayServerDetail struct {
	GroupId        string
	GatewayId      string
	GatewayName    string
	GatewayAddress string
}

func (this *GatewayConfigManageController) buildNginx(serverDetailVOS []*model.GatewayServerDetailVO) error {
	//4. 组装Nginx网关刷新配置信息
	gatewayServerDetailMap := make(map[string][]*model.GatewayServerDetailVO)
	// 将 GatewayServerDetailVO 列表分组到 map 中
	for _, detail := range serverDetailVOS {
		gatewayServerDetailMap[detail.GroupId] = append(gatewayServerDetailMap[detail.GroupId], detail)
	}
	// 获取所有唯一的 GroupId 列表
	var uniqueGroupIdList []string
	for groupId := range gatewayServerDetailMap {
		uniqueGroupIdList = append(uniqueGroupIdList, groupId)
	}
	// 4.1 Location 信息
	locationVos := make([]*model2.LocationVo, 0)
	for _, name := range uniqueGroupIdList {
		// location /10001/ {
		//     rewrite ^/10001/(.*)$ /$1 break;
		// 	   proxy_pass http://10001;
		// }
		locationVo := &model2.LocationVo{
			Name:       "/" + name + "/",
			Proxy_pass: "http://" + name + ";",
		}
		locationVos = append(locationVos, locationVo)
	}
	// 4.2 Upstream 信息
	upstreamVos := make([]*model2.UpstreamVo, 0)
	for _, name := range uniqueGroupIdList {
		// upstream 10001 {
		//     least_conn;
		//     server 172.20.10.12:9001;
		//     #server 172.20.10.12:9002;
		// }
		servers := make([]string, 0) // 创建一个空的字符串切片
		// 遍历 map 中的 GatewayServerDetailVO 切片
		for _, detail := range gatewayServerDetailMap[name] {
			servers = append(servers, detail.GatewayAddress) // 将地址添加到切片中
		}
		upstreamVo := &model2.UpstreamVo{
			Name:     name,
			Strategy: "least_conn;",
			Servers:  servers,
		}
		upstreamVos = append(upstreamVos, upstreamVo)
	}
	nginxConfig := &model2.NginxConfig{LocationList: locationVos, UpstreamList: upstreamVos}
	return this.loadBalancingService.UpdateNginxConfig(nginxConfig)
}
